broadway: Use textures to configure window contents
authorAlexander Larsson <alexl@redhat.com>
Sat, 18 Nov 2017 19:36:57 +0000 (20:36 +0100)
committerAlexander Larsson <alexl@redhat.com>
Thu, 23 Nov 2017 09:46:47 +0000 (10:46 +0100)
Instead of using the old buffer code, just use textures to define the
window contents.

15 files changed:
gdk/broadway/broadway-buffer.c [deleted file]
gdk/broadway/broadway-buffer.h [deleted file]
gdk/broadway/broadway-output.c
gdk/broadway/broadway-output.h
gdk/broadway/broadway-protocol.h
gdk/broadway/broadway-server.c
gdk/broadway/broadway-server.h
gdk/broadway/broadway.js
gdk/broadway/broadwayd.c
gdk/broadway/gdkbroadway-server.c
gdk/broadway/gdkbroadway-server.h
gdk/broadway/gdkdisplay-broadway.c
gdk/broadway/gdkwindow-broadway.c
gdk/broadway/gdkwindow-broadway.h
gdk/broadway/meson.build

diff --git a/gdk/broadway/broadway-buffer.c b/gdk/broadway/broadway-buffer.c
deleted file mode 100644 (file)
index d77d1de..0000000
+++ /dev/null
@@ -1,528 +0,0 @@
-#include "config.h"
-
-#include "broadway-buffer.h"
-
-#include <string.h>
-
-/* This code is based on some code from weston with this license:
- *
- * Copyright © 2012 Intel Corporation
- *
- * Permission to use, copy, modify, distribute, and sell this software and
- * its documentation for any purpose is hereby granted without fee, provided
- * that the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of the copyright holders not be used in
- * advertising or publicity pertaining to distribution of the software
- * without specific, written prior permission.  The copyright holders make
- * no representations about the suitability of this software for any
- * purpose.  It is provided "as is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
- * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
- * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-struct entry {
-  int count;
-  int matches;
-  guint32 hash;
-  int x, y;
-  int index;
-};
-
-struct _BroadwayBuffer {
-  guint8 *data;
-  struct entry *table;
-  int width, height, stride;
-  int encoded;
-  int block_stride, length, block_count, shift;
-  int stats[5];
-  int clashes;
-};
-
-static const guint32 prime = 0x1f821e2d;
-static const guint32 end_prime = 0xf907ec81;   /* prime^block_size */
-#if 0
-static const guint32 vprime = 0x0137b89d;
-static const guint32 end_vprime = 0xaea9a281;  /* vprime^block_size */
-#else
-static const guint32 vprime = 0xf907ec81;
-static const guint32 end_vprime = 0xcdb99001;  /* vprime^block_size */
-#endif
-static const guint32 step = 0x0ac93019;
-static const int block_size = 32, block_mask = 31;
-
-static gboolean
-verify_block_match (BroadwayBuffer *buffer, int x, int y,
-                    BroadwayBuffer *prev, struct entry *entry)
-{
-  int i;
-  void *old, *match;
-  int w1, w2, h1, h2;
-
-  w1 = block_size;
-  if (x + block_size > buffer->width)
-    w1 = buffer->width - x;
-
-  h1 = block_size;
-  if (y + block_size > buffer->height)
-    h1 = buffer->height - y;
-
-  w2 = block_size;
-  if (entry->x + block_size > prev->width)
-    w2 = prev->width - entry->x;
-
-  h2 = block_size;
-  if (entry->y + block_size > prev->height)
-    h2 = prev->height - entry->y;
-
-  if (w1 != w2 || h1 != h2)
-    return FALSE;
-
-  for (i = 0; i < h1; i++)
-    {
-      match = buffer->data + (y + i) * buffer->stride + x * 4;
-      old = prev->data + (entry->y + i) * prev->stride + entry->x * 4;
-      if (memcmp (match, old, w1 * 4) != 0)
-        {
-          buffer->clashes++;
-          return FALSE;
-        }
-    }
-
-  return TRUE;
-}
-
-static void
-insert_block (BroadwayBuffer *buffer, guint32 h, int x, int y)
-{
-  struct entry *entry;
-  int i;
-  guint32 collision = 0;
-
-  entry = &buffer->table[h >> buffer->shift];
-  for (i = step; entry->count > 0 && entry->hash != h; i += step)
-    {
-      entry = &buffer->table[(h + i) >> buffer->shift];
-      collision++;
-    }
-
-  entry->hash = h;
-  entry->count++;
-  entry->x = x;
-  entry->y = y;
-  entry->index = (buffer->block_stride * y + x) / block_size;
-
-  if (collision > G_N_ELEMENTS (buffer->stats) - 1)
-    collision = G_N_ELEMENTS (buffer->stats) - 1;
-  buffer->stats[collision]++;
-}
-
-static struct entry *
-lookup_block (BroadwayBuffer *prev, guint32 h)
-{
-  guint32 i;
-  struct entry *entry;
-  int shift = prev->shift;
-
-  for (i = h;
-       entry = &prev->table[i >> shift], entry->count > 0;
-       i += step)
-    {
-      if (entry->hash == h)
-        return entry;
-    }
-
-  return NULL;
-}
-
-struct encoder {
-  guint32 color;
-  guint32 color_run;
-  guint32 delta;
-  guint32 delta_run;
-  GString *dest;
-  int bytes;
-};
-
-/* Encoding:
- *
- *  - all 1 pixel colors are encoded literally
- *
- *  - We don’t need to support colors with alpha 0 and non-zero
- *    color components, as they mean the same on the canvas anyway.
- *    So we use these as special codes:
- *
- *     - 0x00 00 00 00 : one alpha 0 pixel
- *     - 0xaa rr gg bb : one color pixel, alpha > 0
- *     - 0x00 1x xx xx : delta 0 run, x is length, (20 bits)
- *     - 0x00 2x xx xx 0x xxxx yyyy: block ref, block number x (20 bits) at x, y
- *     - 0x00 3x xx xx 0xaarrggbb : solid color run, length x
- *     - 0x00 4x xx xx 0xaarrggbb : delta run, length x
- *
- */
-
-static void
-emit (struct encoder *encoder, guint32 symbol)
-{
-  g_string_append_len (encoder->dest, (char *)&symbol, sizeof (guint32));
-  encoder->bytes += sizeof (guint32);
-}
-
-static void
-encode_run (struct encoder *encoder)
-{
-  if (encoder->color_run == 0 && encoder->delta_run == 0)
-    return;
-
-  if (encoder->color_run >= encoder->delta_run)
-    {
-      if (encoder->color_run == 1)
-        emit (encoder, encoder->color);
-      else
-        {
-          emit (encoder, 0x00300000 | encoder->color_run);
-          emit (encoder, encoder->color);
-        }
-    }
-  else
-    {
-      if (encoder->delta == 0)
-        emit(encoder, 0x00100000 | encoder->delta_run);
-      else
-        {
-          emit(encoder, 0x00400000 | encoder->delta_run);
-          emit(encoder, encoder->delta);
-        }
-    }
-}
-
-static void
-encode_pixel (struct encoder *encoder, guint32 color, guint32 prev_color)
-{
-  guint32 delta = 0;
-  guint32 a, r, g, b;
-
-  if (color == prev_color)
-    delta = 0;
-  else if (prev_color == 0)
-    delta = color;
-  else
-    {
-      a = ((color & 0xff000000) - (prev_color & 0xff000000)) & 0xff000000;
-      r = ((color & 0x00ff0000) - (prev_color & 0x00ff0000)) & 0x00ff0000;
-      g = ((color & 0x0000ff00) - (prev_color & 0x0000ff00)) & 0x0000ff00;
-      b = ((color & 0x000000ff) - (prev_color & 0x000000ff)) & 0x000000ff;
-
-      delta = a | r | g | b;
-    }
-
-  if ((encoder->color != color &&
-       encoder->color_run > encoder->delta_run) ||
-
-      (encoder->delta != delta &&
-       encoder->delta_run > encoder->color_run) ||
-
-      (encoder->delta != delta && encoder->color != color) ||
-
-      (encoder->delta_run == 0xFFFFF || encoder->color_run == 0xFFFFF))
-    {
-      encode_run (encoder);
-
-      encoder->color_run = 1;
-      encoder->color = color;
-      encoder->delta_run = 1;
-      encoder->delta = delta;
-      return;
-    }
-
-  if (encoder->color == color)
-    encoder->color_run++;
-  else
-    {
-      encoder->color_run = 1;
-      encoder->color = color;
-    }
-
-  if (encoder->delta == delta)
-    encoder->delta_run++;
-  else
-    {
-      encoder->delta_run = 1;
-      encoder->delta = delta;
-    }
-}
-
-static void
-encoder_flush (struct encoder *encoder)
-{
-  encode_run (encoder);
-}
-
-
-static void
-encode_block (struct encoder *encoder, struct entry *entry, int x, int y)
-{
-  /* 0x00 2x xx xx 0x xxxx yyyy:
-   *   block ref, block number x (20 bits) at x, y */
-
-  /* FIXME: Maybe don't encode pixels under blocks and just emit
-   * blocks at their position within the stream. */
-
-  emit (encoder, 0x00200000 | entry->index);
-  emit (encoder, (x << 16) | y);
-}
-
-void
-broadway_buffer_destroy (BroadwayBuffer *buffer)
-{
-  g_free (buffer->data);
-  g_free (buffer->table);
-  g_free (buffer);
-}
-
-int
-broadway_buffer_get_width (BroadwayBuffer *buffer)
-{
-  return buffer->width;
-}
-
-int
-broadway_buffer_get_height (BroadwayBuffer *buffer)
-{
-  return buffer->height;
-}
-
-static void
-unpremultiply_line (void *destp, void *srcp, int width)
-{
-  guint32 *src = srcp;
-  guint32 *dest = destp;
-  guint32 *end = src + width;
-  while (src < end)
-    {
-      guint32 pixel;
-      guint8 alpha, r, g, b;
-
-      pixel = *src++;
-
-      alpha = (pixel & 0xff000000) >> 24;
-
-      if (alpha == 0xff)
-        *dest++ = pixel;
-      else if (alpha == 0)
-        *dest++ = 0;
-      else
-        {
-          r = (((pixel & 0xff0000) >> 16) * 255 + alpha / 2) / alpha;
-          g = (((pixel & 0x00ff00) >>  8) * 255 + alpha / 2) / alpha;
-          b = (((pixel & 0x0000ff) >>  0) * 255 + alpha / 2) / alpha;
-          *dest++ = (guint32)alpha << 24 | (guint32)r << 16 | (guint32)g << 8 | (guint32)b;
-        }
-    }
-}
-
-BroadwayBuffer *
-broadway_buffer_create (int width, int height, guint8 *data, int stride)
-{
-  BroadwayBuffer *buffer;
-  int y, bits_required;
-
-  buffer = g_new0 (BroadwayBuffer, 1);
-  buffer->width = width;
-  buffer->stride = width * 4;
-  buffer->height = height;
-
-  buffer->block_stride = (width + block_size - 1) / block_size;
-  buffer->block_count =
-    buffer->block_stride * ((height + block_size - 1) / block_size);
-  bits_required = g_bit_storage (buffer->block_count * 4);
-  buffer->shift = 32 - bits_required;
-  buffer->length = 1 << bits_required;
-
-  buffer->table = g_malloc0 (buffer->length * sizeof buffer->table[0]);
-
-  memset (buffer->stats, 0, sizeof buffer->stats);
-  buffer->clashes = 0;
-
-  buffer->data = g_malloc (buffer->stride * height);
-
-  for (y = 0; y < height; y++)
-    unpremultiply_line (buffer->data + y * buffer->stride, data + y * stride, width);
-
-  return buffer;
-}
-
-void
-broadway_buffer_encode (BroadwayBuffer *buffer, BroadwayBuffer *prev, GString *dest)
-{
-  struct entry *entry;
-  int i, j, k;
-  int x0, x1, y0, y1;
-  guint32 *block_hashes;
-  guint32 hash, bottom_hash, h, *line, *bottom, *prev_line;
-  int width, height;
-  struct encoder encoder = { 0 };
-  int *skyline, skyline_pixels;
-  int matches;
-
-  width = buffer->width;
-  height = buffer->height;
-  x0 = 0;
-  x1 = width;
-  y0 = 0;
-  y1 = height;
-
-  skyline = g_malloc0 ((width + block_size) * sizeof skyline[0]);
-
-  block_hashes = g_malloc0 (width * sizeof block_hashes[0]);
-
-  matches = 0;
-  encoder.dest = dest;
-
-  // Calculate the block hashes for the first row
-  for (i = y0; i < MIN(y1, y0 + block_size); i++)
-    {
-      line = (guint32 *)(buffer->data + i * buffer->stride);
-      hash = 0;
-      for (j = x0; j < MIN(x1, x0 + block_size); j++)
-        hash = hash * prime + line[j];
-      for (; j < x0 + block_size; j++)
-        hash = hash * prime;
-
-      for (j = x0; j < x1; j++)
-        {
-          block_hashes[j] = block_hashes[j] * vprime + hash;
-
-          hash = hash * prime - line[j] * end_prime;
-          if (j + block_size < width)
-            hash += line[j + block_size];
-        }
-    }
-  // Do the last rows if height < block_size
-  for (; i < y0 + block_size; i++)
-    {
-      for (j = x0; j < x1; j++)
-        block_hashes[j] = block_hashes[j] * vprime;
-    }
-
-  for (i = y0; i < y1; i++)
-    {
-      line = (guint32 *) (buffer->data + i * buffer->stride);
-      bottom = (guint32 *) (buffer->data + (i + block_size) * buffer->stride);
-      bottom_hash = 0;
-      hash = 0;
-      skyline_pixels = 0;
-
-      if (prev && i < prev->height)
-        prev_line = (guint32 *) (prev->data + i * prev->stride);
-      else
-        prev_line = NULL;
-
-      for (j = x0; j < x0 + block_size; j++)
-        {
-          hash = hash * prime;
-          if (j < width)
-            hash += line[j];
-          if (i + block_size < height)
-            {
-              bottom_hash = bottom_hash * prime;
-              if (j < width)
-                bottom_hash += bottom[j];
-            }
-          if (i < skyline[j])
-            skyline_pixels = 0;
-          else
-            skyline_pixels++;
-        }
-
-      for (j = x0; j < x1; j++)
-        {
-          if (i < skyline[j])
-            encode_pixel (&encoder, line[j], line[j]);
-          else if (prev)
-            {
-              /* FIXME: Add back overlap exception
-               * for consecutive blocks */
-
-              h = block_hashes[j];
-              entry = lookup_block (prev, h);
-              if (entry && entry->count < 2 &&
-                  skyline_pixels >= block_size &&
-                  verify_block_match (buffer, j, i, prev, entry) &&
-                  (entry->x != j || entry->y != i))
-                {
-                  matches++;
-                  encode_block (&encoder, entry, j, i);
-
-                  for (k = 0; k < block_size; k++)
-                    skyline[j + k] = i + block_size;
-
-                  encode_pixel (&encoder, line[j], line[j]);
-                }
-              else
-                {
-                  if (prev_line && j < prev->width)
-                    encode_pixel (&encoder, line[j],
-                                  prev_line[j]);
-                  else
-                    encode_pixel (&encoder, line[j], 0);
-                }
-            }
-          else
-            encode_pixel (&encoder, line[j], 0);
-
-          if (i < skyline[j + block_size])
-            skyline_pixels = 0;
-          else
-            skyline_pixels++;
-
-          /* Insert block in hash table if we're on a
-           * grid point. */
-          if (((i | j) & block_mask) == 0 && !buffer->encoded)
-            insert_block (buffer, block_hashes[j], j, i);
-
-          /* Update sliding block hash */
-          block_hashes[j] =
-            block_hashes[j] * vprime + bottom_hash -
-            hash * end_vprime;
-
-          if (i + block_size < height)
-            {
-              bottom_hash = bottom_hash * prime - bottom[j] * end_prime;
-              if (j + block_size < width)
-                bottom_hash += bottom[j + block_size];
-            }
-          hash = hash * prime - line[j] * end_prime;
-          if  (j + block_size < width)
-            hash += line[j + block_size] ;
-        }
-    }
-
-  encoder_flush (&encoder);
-
-#if 0
-  fprintf(stderr, "collision stats:");
-  for (i = 0; i < (int) G_N_ELEMENTS(buffer->stats); i++)
-    fprintf(stderr, "%c%d", i == 0 ? ' ' : '/', buffer->stats[i]);
-  fprintf(stderr, "\n");
-
-  fprintf(stderr, "%d / %d blocks (%d%%) matched, %d clashes\n",
-          matches, buffer->block_count,
-          100 * matches / buffer->block_count, buffer->clashes);
-
-  fprintf(stderr, "output stream %d bytes, raw buffer %d bytes (%d%%)\n",
-          encoder.bytes, height * buffer->stride,
-          100 * encoder.bytes / (height * buffer->stride));
-#endif
-
-  g_free (skyline);
-  g_free (block_hashes);
-
-  buffer->encoded = TRUE;
-}
diff --git a/gdk/broadway/broadway-buffer.h b/gdk/broadway/broadway-buffer.h
deleted file mode 100644 (file)
index 9bc5f46..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef __BROADWAY_BUFFER__
-#define __BROADWAY_BUFFER__
-
-#include "broadway-protocol.h"
-#include <glib-object.h>
-
-typedef struct _BroadwayBuffer BroadwayBuffer;
-
-BroadwayBuffer *broadway_buffer_create     (int             width,
-                                            int             height,
-                                            guint8         *data,
-                                            int             stride);
-void            broadway_buffer_destroy    (BroadwayBuffer *buffer);
-void            broadway_buffer_encode     (BroadwayBuffer *buffer,
-                                            BroadwayBuffer *prev,
-                                            GString        *dest);
-int             broadway_buffer_get_width  (BroadwayBuffer *buffer);
-int             broadway_buffer_get_height (BroadwayBuffer *buffer);
-
-#endif /* __BROADWAY_BUFFER__ */
index b9a86daf61f6ad83841d128c425353bfd09ce089..770fa438b51d5bbea0afb9bc6aede73bf8ecbf70 100644 (file)
@@ -287,48 +287,14 @@ broadway_output_set_transient_for (BroadwayOutput *output,
 }
 
 void
-broadway_output_put_buffer (BroadwayOutput *output,
-                            int             id,
-                            BroadwayBuffer *prev_buffer,
-                            BroadwayBuffer *buffer)
+broadway_output_window_update (BroadwayOutput *output,
+                              int             id,
+                              guint32         texture)
 {
-  gsize len;
-  int w, h;
-  GZlibCompressor *compressor;
-  GOutputStream *out, *out_mem;
-  GString *encoded;
-
-  write_header (output, BROADWAY_OP_PUT_BUFFER);
-
-  w = broadway_buffer_get_width (buffer);
-  h = broadway_buffer_get_height (buffer);
+  write_header (output, BROADWAY_OP_WINDOW_UPDATE);
 
   append_uint16 (output, id);
-  append_uint16 (output, w);
-  append_uint16 (output, h);
-
-  encoded = g_string_new ("");
-  broadway_buffer_encode (buffer, prev_buffer, encoded);
-
-  compressor = g_zlib_compressor_new (G_ZLIB_COMPRESSOR_FORMAT_RAW, -1);
-  out_mem = g_memory_output_stream_new_resizable ();
-  out = g_converter_output_stream_new (out_mem, G_CONVERTER (compressor));
-  g_object_unref (compressor);
-
-  if (!g_output_stream_write_all (out, encoded->str, encoded->len,
-                                  NULL, NULL, NULL) ||
-      !g_output_stream_close (out, NULL, NULL))
-    g_warning ("compression failed");
-
-
-  len = g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (out_mem));
-  append_uint32 (output, len);
-
-  g_string_append_len (output->buf, g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (out_mem)), len);
-
-  g_string_free (encoded, TRUE);
-  g_object_unref (out);
-  g_object_unref (out_mem);
+  append_uint32 (output, texture);
 }
 
 void
index 784ae179dbfbaee72c6a0fdb9f6dd2b084a54bc2..7c69e3bd8ff744e38bc344f0960331822a3f38e6 100644 (file)
@@ -4,7 +4,6 @@
 #include <glib.h>
 #include <gio/gio.h>
 #include "broadway-protocol.h"
-#include "broadway-buffer.h"
 
 typedef struct BroadwayOutput BroadwayOutput;
 
@@ -54,10 +53,9 @@ void            broadway_output_move_resize_surface (BroadwayOutput *output,
 void            broadway_output_set_transient_for (BroadwayOutput *output,
                                                   int             id,
                                                   int             parent_id);
-void            broadway_output_put_buffer      (BroadwayOutput *output,
+void            broadway_output_window_update   (BroadwayOutput *output,
                                                 int             id,
-                                                 BroadwayBuffer *prev_buffer,
-                                                 BroadwayBuffer *buffer);
+                                                guint32         texture);
 void            broadway_output_upload_texture (BroadwayOutput *output,
                                                guint32 id,
                                                GBytes *texture);
index 2fa93d4182fbf2c9581f00be394abee2b176c4b4..3bf963f74e16d95e557b6a4864f57645885991b8 100644 (file)
@@ -41,7 +41,7 @@ typedef enum {
   BROADWAY_OP_REQUEST_AUTH = 'l',
   BROADWAY_OP_AUTH_OK = 'L',
   BROADWAY_OP_DISCONNECTED = 'D',
-  BROADWAY_OP_PUT_BUFFER = 'b',
+  BROADWAY_OP_WINDOW_UPDATE = 'b',
   BROADWAY_OP_SET_SHOW_KEYBOARD = 'k',
   BROADWAY_OP_UPLOAD_TEXTURE = 't',
   BROADWAY_OP_RELEASE_TEXTURE = 'T',
@@ -193,9 +193,7 @@ typedef struct {
 typedef struct {
   BroadwayRequestBase base;
   guint32 id;
-  char name[36];
-  guint32 width;
-  guint32 height;
+  guint32 texture;
 } BroadwayRequestUpdate;
 
 typedef struct {
index 6d5dde86fe57440ad64217b4c115021006e88acd..8d86a9e0694992ede902353bf206504a076b974f 100644 (file)
@@ -116,12 +116,7 @@ struct BroadwayWindow {
   gboolean is_temp;
   gboolean visible;
   gint32 transient_for;
-
-  BroadwayBuffer *buffer;
-  gboolean buffer_synced;
-
-  char *cached_surface_name;
-  cairo_surface_t *cached_surface;
+  guint32 texture;
 };
 
 static void broadway_server_resync_windows (BroadwayServer *server);
@@ -826,87 +821,6 @@ broadway_server_block_for_input (BroadwayServer *server, char op,
 }
 #endif
 
-static void *
-map_named_shm (char *name, gsize size)
-{
-#ifdef G_OS_UNIX
-
-  int fd;
-  void *ptr;
-  char *filename = NULL;
-
-  fd = shm_open (name, O_RDONLY, 0600);
-  if (fd == -1)
-    {
-      filename = g_build_filename (g_get_tmp_dir (), name, NULL);
-      fd = open (filename, O_RDONLY);
-      if (fd == -1)
-       {
-         perror ("Failed to map shm");
-         g_free (filename);
-
-         return NULL;
-       }
-    }
-
-  ptr = mmap (0, size, PROT_READ, MAP_SHARED, fd, 0);
-
-  (void) close (fd);
-
-  if (filename)
-    {
-      unlink (filename);
-      g_free (filename);
-    }
-  else
-    shm_unlink (name);
-
-  return ptr;
-
-#elif defined(G_OS_WIN32)
-
-  int fd;
-  void *ptr;
-  char *shmpath;
-  void *map = ((void *)-1);
-
-  if (*name == '/')
-    ++name;
-  shmpath = g_build_filename (g_get_tmp_dir (), name, NULL);
-
-  fd = open(shmpath, O_RDONLY, 0600);
-  if (fd == -1)
-    {
-      g_free (shmpath);
-      perror ("Failed to shm_open");
-      return NULL;
-    }
-
-  if (size == 0)
-    ptr = map;
-  else
-    {
-      HANDLE h, fm;
-      h = (HANDLE)_get_osfhandle (fd);
-      fm = CreateFileMapping (h, NULL, PAGE_READONLY, 0, (DWORD)size, NULL);
-      ptr = MapViewOfFile (fm, FILE_MAP_READ, 0, 0, (size_t)size);
-      CloseHandle (fm);
-    }
-
-  (void) close(fd);
-
-  remove (shmpath);
-  g_free (shmpath);
-
-  return ptr;
-
-#else
-#error "No shm mapping supported"
-
-  return NULL;
-#endif
-}
-
 static const char *
 parse_line (const char *line, const char *key)
 {
@@ -1463,10 +1377,6 @@ broadway_server_destroy_window (BroadwayServer *server,
       g_hash_table_remove (server->id_ht,
                           GINT_TO_POINTER (id));
 
-      g_free (window->cached_surface_name);
-      if (window->cached_surface != NULL)
-       cairo_surface_destroy (window->cached_surface);
-
       g_free (window);
     }
 }
@@ -1601,39 +1511,22 @@ broadway_server_has_client (BroadwayServer *server)
 }
 
 void
-broadway_server_window_update (BroadwayServer *server,
-                              gint id,
-                              cairo_surface_t *surface)
+broadway_server_window_update (BroadwayServer   *server,
+                              gint              id,
+                              guint32           texture)
 {
   BroadwayWindow *window;
-  BroadwayBuffer *buffer;
-
-  if (surface == NULL)
-    return;
 
   window = g_hash_table_lookup (server->id_ht,
                                GINT_TO_POINTER (id));
   if (window == NULL)
     return;
 
-  g_assert (window->width == cairo_image_surface_get_width (surface));
-  g_assert (window->height == cairo_image_surface_get_height (surface));
-
-  buffer = broadway_buffer_create (window->width, window->height,
-                                   cairo_image_surface_get_data (surface),
-                                   cairo_image_surface_get_stride (surface));
+  window->texture = texture;
 
   if (server->output != NULL)
-    {
-      window->buffer_synced = TRUE;
-      broadway_output_put_buffer (server->output, window->id,
-                                  window->buffer, buffer);
-    }
-
-  if (window->buffer)
-    broadway_buffer_destroy (window->buffer);
-
-  window->buffer = buffer;
+    broadway_output_window_update (server->output, window->id,
+                                  window->texture);
 }
 
 guint32
@@ -1788,78 +1681,6 @@ broadway_server_ungrab_pointer (BroadwayServer *server,
   return serial;
 }
 
-static const cairo_user_data_key_t shm_cairo_key;
-
-typedef struct {
-  void *data;
-  gsize data_size;
-} ShmSurfaceData;
-
-static void
-shm_data_unmap (void *_data)
-{
-  ShmSurfaceData *data = _data;
-#ifdef G_OS_UNIX
-  munmap (data->data, data->data_size);
-#elif defined(G_OS_WIN32)
-  UnmapViewOfFile (data->data);
-#endif
-  g_free (data);
-}
-
-cairo_surface_t *
-broadway_server_open_surface (BroadwayServer *server,
-                             guint32 id,
-                             char *name,
-                             int width,
-                             int height)
-{
-  BroadwayWindow *window;
-  ShmSurfaceData *data;
-  cairo_surface_t *surface;
-  gsize size;
-  void *ptr;
-
-  window = g_hash_table_lookup (server->id_ht,
-                               GINT_TO_POINTER (id));
-  if (window == NULL)
-    return NULL;
-
-  if (window->cached_surface_name != NULL &&
-      strcmp (name, window->cached_surface_name) == 0)
-    return cairo_surface_reference (window->cached_surface);
-
-  size = width * height * sizeof (guint32);
-
-  ptr = map_named_shm (name, size);
-
-  if (ptr == NULL)
-    return NULL;
-
-  data = g_new0 (ShmSurfaceData, 1);
-
-  data->data = ptr;
-  data->data_size = size;
-
-  surface = cairo_image_surface_create_for_data ((guchar *)data->data,
-                                                CAIRO_FORMAT_ARGB32,
-                                                width, height,
-                                                width * sizeof (guint32));
-  g_assert (surface != NULL);
-
-  cairo_surface_set_user_data (surface, &shm_cairo_key,
-                              data, shm_data_unmap);
-
-  g_free (window->cached_surface_name);
-  window->cached_surface_name = g_strdup (name);
-
-  if (window->cached_surface != NULL)
-    cairo_surface_destroy (window->cached_surface);
-  window->cached_surface = cairo_surface_reference (surface);
-
-  return surface;
-}
-
 guint32
 broadway_server_new_window (BroadwayServer *server,
                            int x,
@@ -1929,7 +1750,6 @@ broadway_server_resync_windows (BroadwayServer *server)
       if (window->id == 0)
        continue; /* Skip root */
 
-      window->buffer_synced = FALSE;
       broadway_output_new_surface (server->output,
                                   window->id,
                                   window->x,
@@ -1948,18 +1768,14 @@ broadway_server_resync_windows (BroadwayServer *server)
        continue; /* Skip root */
 
       if (window->transient_for != -1)
-       broadway_output_set_transient_for (server->output, window->id, window->transient_for);
+       broadway_output_set_transient_for (server->output, window->id,
+                                          window->transient_for);
+
+      broadway_output_window_update (server->output, window->id,
+                                    window->texture);
+
       if (window->visible)
-       {
-         broadway_output_show_surface (server->output, window->id);
-
-         if (window->buffer != NULL)
-           {
-             window->buffer_synced = TRUE;
-              broadway_output_put_buffer (server->output, window->id,
-                                          NULL, window->buffer);
-           }
-       }
+       broadway_output_show_surface (server->output, window->id);
     }
 
   if (server->show_keyboard)
index 7cb7694a5bafcdcdbe18c0c94b71753bec9318c3..422488c0386734be389133bec85d8f91a3c9ff08 100644 (file)
@@ -84,7 +84,7 @@ cairo_surface_t   * broadway_server_create_surface           (int
                                                              int               height);
 void                broadway_server_window_update            (BroadwayServer   *server,
                                                              gint              id,
-                                                             cairo_surface_t  *surface);
+                                                             guint32           texture);
 gboolean            broadway_server_window_move_resize       (BroadwayServer   *server,
                                                              gint              id,
                                                              gboolean          with_move,
@@ -94,10 +94,5 @@ gboolean            broadway_server_window_move_resize       (BroadwayServer   *
                                                              int               height);
 void                broadway_server_focus_window             (BroadwayServer   *server,
                                                               gint              new_focused_window);
-cairo_surface_t * broadway_server_open_surface (BroadwayServer *server,
-                                               guint32 id,
-                                               char *name,
-                                               int width,
-                                               int height);
 
 #endif /* __BROADWAY_SERVER__ */
index 12578d78ae4faa44cb54d01427d5dc9d60edc72c..b268e0da6b5643a232f15add432f72bd9444aa84 100644 (file)
@@ -67,25 +67,6 @@ function logStackTrace(len) {
        log(callstack[i]);
 }
 
-function resizeCanvas(canvas, w, h)
-{
-    /* Canvas resize clears the data, so we need to save it first */
-    var tmpCanvas = canvas.ownerDocument.createElement("canvas");
-    tmpCanvas.width = canvas.width;
-    tmpCanvas.height = canvas.height;
-    var tmpContext = tmpCanvas.getContext("2d");
-    tmpContext.globalCompositeOperation = "copy";
-    tmpContext.drawImage(canvas, 0, 0, tmpCanvas.width, tmpCanvas.height);
-
-    canvas.width = w;
-    canvas.height = h;
-
-    var context = canvas.getContext("2d");
-
-    context.globalCompositeOperation = "copy";
-    context.drawImage(tmpCanvas, 0, 0, tmpCanvas.width, tmpCanvas.height);
-}
-
 var grab = new Object();
 grab.window = null;
 grab.ownerEvents = false;
@@ -160,15 +141,15 @@ function cmdCreateSurface(id, x, y, width, height, isTemp)
     surface.visible = false;
     surface.imageData = null;
 
-    var canvas = document.createElement("canvas");
-    canvas.width = width;
-    canvas.height = height;
-    canvas.surface = surface;
-    surface.canvas = canvas;
+    var image = new Image();
+    image.width = width;
+    image.height = height;
+    image.surface = surface;
+    surface.image = image;
     var toplevelElement;
 
-    toplevelElement = canvas;
-    document.body.appendChild(canvas);
+    toplevelElement = image;
+    document.body.appendChild(image);
 
     surface.toplevelElement = toplevelElement;
     toplevelElement.style["position"] = "absolute";
@@ -268,8 +249,8 @@ function cmdDeleteSurface(id)
     var i = stackingOrder.indexOf(surface);
     if (i >= 0)
        stackingOrder.splice(i, 1);
-    var canvas = surface.canvas;
-    canvas.parentNode.removeChild(canvas);
+    var image = surface.image;
+    image.parentNode.removeChild(image);
     delete surfaces[id];
 }
 
@@ -286,15 +267,17 @@ function cmdMoveResizeSurface(id, has_pos, x, y, has_size, w, h)
        surface.height = h;
     }
 
-    if (has_size)
-       resizeCanvas(surface.canvas, w, h);
+    if (has_size) {
+       surface.image.width = w;
+       surface.image.height = h;
+    }
 
     if (surface.visible) {
        if (has_pos) {
            var xOffset = surface.x;
            var yOffset = surface.y;
 
-           var element = surface.canvas;
+           var element = surface.image;
 
            element.style["left"] = xOffset + "px";
            element.style["top"] = yOffset + "px";
@@ -512,21 +495,12 @@ function decodeBuffer(context, oldData, w, h, data, debug)
     return imageData;
 }
 
-function cmdPutBuffer(id, w, h, compressed)
+function cmdWindowUpdate(id, texture_id)
 {
     var surface = surfaces[id];
-    var context = surface.canvas.getContext("2d");
-
-    var inflate = new Zlib.RawInflate(compressed);
-    var data = inflate.decompress();
-
-    var imageData = decodeBuffer (context, surface.imageData, w, h, data, debugDecoding);
-    context.putImageData(imageData, 0, 0);
-
-    if (debugDecoding)
-        imageData = decodeBuffer (context, surface.imageData, w, h, data, false);
+    var texture_url = textures[texture];
 
-    surface.imageData = imageData;
+    surface.image.src = texture_url;
 }
 
 function cmdUploadTexture(id, data)
@@ -631,12 +605,10 @@ function handleCommands(cmd)
            cmdLowerSurface(id);
            break;
 
-       case 'b': // Put image buffer
+       case 'b': // Update window
            id = cmd.get_16();
-           w = cmd.get_16();
-           h = cmd.get_16();
-            var data = cmd.get_data();
-            cmdPutBuffer(id, w, h, data);
+           texture = cmd.get_32();
+            cmdWindowUpdate(id, texture);
             break;
 
        case 't': // Upload texture
index ee0cd5fa002376cd592d8f2f4960b6158abe9e41..2706cc95808f0786b646355c70e499fefa0aadc2 100644 (file)
@@ -225,7 +225,6 @@ client_handle_request (BroadwayClient *client,
   BroadwayReplyQueryMouse reply_query_mouse;
   BroadwayReplyGrabPointer reply_grab_pointer;
   BroadwayReplyUngrabPointer reply_ungrab_pointer;
-  cairo_surface_t *surface;
   guint32 before_serial, now_serial;
   guint32 global_id;
   int fd;
@@ -284,18 +283,11 @@ client_handle_request (BroadwayClient *client,
                                                request->set_transient_for.parent);
       break;
     case BROADWAY_REQUEST_UPDATE:
-      surface = broadway_server_open_surface (server,
-                                             request->update.id,
-                                             request->update.name,
-                                             request->update.width,
-                                             request->update.height);
-      if (surface != NULL)
-       {
-         broadway_server_window_update (server,
-                                        request->update.id,
-                                        surface);
-         cairo_surface_destroy (surface);
-       }
+      global_id = GPOINTER_TO_INT (g_hash_table_lookup (client->textures,
+                                                       GINT_TO_POINTER (request->update.texture)));
+      broadway_server_window_update (server,
+                                    request->update.id,
+                                    global_id);
       break;
     case BROADWAY_REQUEST_UPLOAD_TEXTURE:
       if (client->fds == NULL)
index 2ee75ab12875194e642fce352b7d3b3f0f61efd1..40238337ff5b609676d5c9f69dfe4ab2b6aa2131 100644 (file)
@@ -552,229 +552,15 @@ _gdk_broadway_server_window_set_transient_for (GdkBroadwayServer *server,
                                    BROADWAY_REQUEST_SET_TRANSIENT_FOR);
 }
 
-static void *
-map_named_shm (char *name, gsize size, gboolean *is_shm)
-{
-#ifdef G_OS_UNIX
-
-  char *filename = NULL;
-  int fd;
-  void *ptr;
-  int res;
-
-  fd = shm_open(name, O_RDWR|O_CREAT|O_EXCL, 0600);
-  if (fd == -1)
-    {
-      if (errno == EEXIST)
-       return NULL;
-
-      filename = g_build_filename (g_get_tmp_dir (), name, NULL);
-
-      fd = open (filename, O_RDWR | O_CREAT | O_EXCL, 0600);
-      g_free (filename);
-      if (fd == -1)
-       {
-         if (errno != EEXIST)
-           g_error ("Unable to allocate shared mem for window");
-         return NULL;
-       }
-      else
-       *is_shm = FALSE;
-    }
-  else
-    *is_shm = TRUE;
-
-  res = ftruncate (fd, size);
-  g_assert (res != -1);
-
-#ifdef HAVE_POSIX_FALLOCATE
-  res = posix_fallocate (fd, 0, size);
-  if (res != 0 && errno == ENOSPC)
-    {
-      if (filename)
-       unlink (filename);
-      else
-       shm_unlink (name);
-      g_error ("Not enough shared memory for window surface");
-    }
-#endif
-
-  ptr = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
-
-  (void) close(fd);
-
-  return ptr;
-
-#elif defined(G_OS_WIN32)
-
-  int fd;
-  void *ptr;
-  char *shmpath;
-  void *map = ((void *)-1);
-  int res;
-
-  if (*name == '/')
-    ++name;
-  shmpath = g_build_filename (g_get_tmp_dir (), name, NULL);
-
-  fd = open(shmpath, O_RDWR|O_CREAT|O_EXCL, 0600);
-  g_free (shmpath);
-  if (fd == -1)
-    {
-      if (errno != EEXIST)
-       g_error ("Unable to allocate shared mem for window");
-      return NULL;
-    }
-
-  *is_shm = TRUE;
-  res = ftruncate (fd, size);
-  g_assert (res != -1);
-  
-  if (size == 0)
-    ptr = map;
-  else
-    {
-      HANDLE h, fm;
-      h = (HANDLE)_get_osfhandle (fd);
-      fm = CreateFileMapping (h, NULL, PAGE_READWRITE, 0, (DWORD)size, NULL);
-      ptr = MapViewOfFile (fm, FILE_MAP_WRITE, 0, 0, (size_t)size);
-      CloseHandle (fm);
-    }
-
-  (void) close(fd);
-
-  return ptr;
-
-#else
-#error "No shm mapping supported"
-
-  return NULL;
-#endif
-}
-
-static char
-make_valid_fs_char (char c)
-{
-  char chars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890";
-
-  return chars[c % (sizeof (chars) - 1)];
-}
-
-/* name must have at least space for 34 bytes */
-static gpointer
-create_random_shm (char *name, gsize size, gboolean *is_shm)
-{
-  guint32 r;
-  int i, o;
-  gpointer ptr;
-
-  while (TRUE)
-    {
-      o = 0;
-      name[o++] = '/';
-      name[o++] = 'b';
-      name[o++] = 'd';
-      name[o++] = 'w';
-      name[o++] = '-';
-      for (i = 0; i < 32/4 - 1; i++)
-       {
-         r = g_random_int ();
-         name[o++] = make_valid_fs_char ((r >> 0) & 0xff);
-         name[o++] = make_valid_fs_char ((r >> 8) & 0xff);
-         name[o++] = make_valid_fs_char ((r >> 16) & 0xff);
-         name[o++] = make_valid_fs_char ((r >> 24) & 0xff);
-       }
-      name[o++] = 0;
-
-      ptr = map_named_shm (name, size, is_shm);
-      if (ptr)
-       return ptr;
-    }
-}
-
-static const cairo_user_data_key_t gdk_broadway_shm_cairo_key;
-
-typedef struct {
-  char name[36];
-  void *data;
-  gsize data_size;
-  gboolean is_shm;
-} BroadwayShmSurfaceData;
-
-static void
-shm_data_destroy (void *_data)
-{
-  BroadwayShmSurfaceData *data = _data;
-
-#ifdef G_OS_UNIX
-
-  munmap (data->data, data->data_size);
-  if (data->is_shm)
-    shm_unlink (data->name);
-  else
-    {
-      char *filename = g_build_filename (g_get_tmp_dir (), data->name, NULL);
-      unlink (filename);
-      g_free (filename);
-    }
-
-#elif defined(G_OS_WIN32)
-
-  char *name = data->name;
-  char *shmpath;
-
-  if (*name == '/')
-    ++name;
-
-  shmpath = g_build_filename (g_get_tmp_dir (), name, NULL);
-  UnmapViewOfFile (data->data);
-  remove (shmpath);
-  g_free (shmpath);
-
-#endif
-
-  g_free (data);
-}
-
-cairo_surface_t *
-_gdk_broadway_server_create_surface (int                 width,
-                                    int                 height)
-{
-  BroadwayShmSurfaceData *data;
-  cairo_surface_t *surface;
-
-  data = g_new (BroadwayShmSurfaceData, 1);
-  data->data_size = width * height * sizeof (guint32);
-  data->data = create_random_shm (data->name, data->data_size, &data->is_shm);
-
-  surface = cairo_image_surface_create_for_data ((guchar *)data->data,
-                                                CAIRO_FORMAT_ARGB32, width, height, width * sizeof (guint32));
-  g_assert (surface != NULL);
-  
-  cairo_surface_set_user_data (surface, &gdk_broadway_shm_cairo_key,
-                              data, shm_data_destroy);
-
-  return surface;
-}
-
 void
 _gdk_broadway_server_window_update (GdkBroadwayServer *server,
                                    gint id,
-                                   cairo_surface_t *surface)
+                                   guint32 texture)
 {
   BroadwayRequestUpdate msg;
-  BroadwayShmSurfaceData *data;
-
-  if (surface == NULL)
-    return;
-
-  data = cairo_surface_get_user_data (surface, &gdk_broadway_shm_cairo_key);
-  g_assert (data != NULL);
 
   msg.id = id;
-  memcpy (msg.name, data->name, 36);
-  msg.width = cairo_image_surface_get_width (surface);
-  msg.height = cairo_image_surface_get_height (surface);
+  msg.texture = texture;
 
   gdk_broadway_server_send_message (server, msg,
                                    BROADWAY_REQUEST_UPDATE);
index ea16e5598f4681e41ab36cba96425ba650939946..91554e5eae9017b36519e51a67158a63f7bd74aa 100644 (file)
@@ -63,11 +63,9 @@ guint32             gdk_broadway_server_upload_texture           (GdkBroadwaySer
                                                                   GdkTexture         *texture);
 void                gdk_broadway_server_release_texture          (GdkBroadwayServer  *server,
                                                                   guint32             id);
-cairo_surface_t   *_gdk_broadway_server_create_surface           (int                 width,
-                                                                 int                 height);
 void               _gdk_broadway_server_window_update            (GdkBroadwayServer  *server,
                                                                  gint                id,
-                                                                 cairo_surface_t    *surface);
+                                                                 guint32             texture);
 gboolean           _gdk_broadway_server_window_move_resize       (GdkBroadwayServer  *server,
                                                                  gint                id,
                                                                  gboolean            with_move,
index c5eede1a94515f967378c11132f22c544f9659f5..aa2c0f6257d26443dd459d6e1b34dc41c4a4c133 100644 (file)
@@ -30,6 +30,7 @@
 #include "gdkinternals.h"
 #include "gdkdeviceprivate.h"
 #include "gdkdevicemanager-broadway.h"
+#include <gdk/gdktextureprivate.h>
 
 #include <glib.h>
 #include <glib/gprintf.h>
index ce02f97510f72762a771e591ad684ee4f64f1cab..2f05c31ab93b73fc19cf7099927de865e5acc1dc 100644 (file)
@@ -36,6 +36,7 @@
 #include "gdkinternals.h"
 #include "gdkdeviceprivate.h"
 #include "gdkeventsource.h"
+#include <gdk/gdktextureprivate.h>
 
 #include <stdlib.h>
 #include <stdio.h>
@@ -112,11 +113,26 @@ update_dirty_windows_and_sync (void)
 
       if (impl->dirty)
        {
+         GdkTexture *texture;
+         guint32 texture_id;
+
          impl->dirty = FALSE;
          updated_surface = TRUE;
+
+         if (impl->texture_id)
+           gdk_broadway_server_release_texture (display->server, impl->texture_id);
+         impl->texture_id = 0;
+
+         texture = gdk_texture_new_for_surface (impl->surface);
+         texture_id =  gdk_broadway_server_upload_texture (display->server, texture);
+         g_object_unref (texture);
+
+         impl->texture_id = texture_id;
+
          _gdk_broadway_server_window_update (display->server,
                                              impl->id,
-                                             impl->surface);
+                                             texture_id);
+
        }
     }
 
@@ -246,8 +262,9 @@ _gdk_broadway_window_resize_surface (GdkWindow *window)
     {
       cairo_surface_destroy (impl->surface);
 
-      impl->surface = _gdk_broadway_server_create_surface (gdk_window_get_width (impl->wrapper),
-                                                          gdk_window_get_height (impl->wrapper));
+      impl->surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+                                                 gdk_window_get_width (impl->wrapper),
+                                                 gdk_window_get_height (impl->wrapper));
     }
 
   if (impl->ref_surface)
@@ -283,7 +300,7 @@ gdk_window_broadway_ref_cairo_surface (GdkWindow *window)
 
   /* Create actual backing store if missing */
   if (!impl->surface)
-    impl->surface = _gdk_broadway_server_create_surface (w, h);
+    impl->surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, w, h);
 
   /* Create a destroyable surface referencing the real one */
   if (!impl->ref_surface)
@@ -334,6 +351,9 @@ _gdk_broadway_window_destroy (GdkWindow *window,
   g_hash_table_remove (broadway_display->id_ht, GINT_TO_POINTER (impl->id));
 
   _gdk_broadway_server_destroy_window (broadway_display->server, impl->id);
+  if (impl->texture_id)
+    gdk_broadway_server_release_texture (broadway_display->server, impl->texture_id);
+
 }
 
 /* This function is called when the XWindow is really gone.
index 5fe7c78026a74ccc2d6d55837c4fa9bbb710383b..4a2a7279768a092011cc77ddacd94a8ee224f415 100644 (file)
@@ -55,6 +55,7 @@ struct _GdkWindowImplBroadway
   GdkCursor *cursor;
 
   int id;
+  int texture_id;
 
   gboolean visible;
   gboolean maximized;
index 4534a9d747ab884f77459f6e0f7c45e26995cef8..70b11a2adec9e32a04e952ceee68989c1bcbab65 100644 (file)
@@ -1,5 +1,4 @@
 gdk_broadway_sources = files([
-  'broadway-buffer.c',
   'broadway-output.c',
   'broadway-server.c',
   'broadwayd.c',
@@ -60,7 +59,7 @@ broadwayjs_h = custom_target('broadwayjs.h',
 
 executable('gtk4-broadwayd',
   clienthtml_h, broadwayjs_h,
-  'broadwayd.c', 'broadway-server.c', 'broadway-buffer.c', 'broadway-output.c',
+  'broadwayd.c', 'broadway-server.c', 'broadway-output.c',
   include_directories: [confinc, gdkinc],
   c_args: ['-DGDK_COMPILATION', '-DG_LOG_DOMAIN="Gdk"', ],
   dependencies : [broadwayd_syslib, gdk_deps],